/*
Copyright 2017 yangchong211（github.com/yangchong211）

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package com.yc.video.controller;

import ohos.aafwk.ability.Ability;
import ohos.aafwk.ability.DataAbilityHelper;
import ohos.agp.animation.Animator;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.components.LayoutScatter;
import ohos.agp.components.StackLayout;
import ohos.app.AbilityContext;
import ohos.app.Context;
import ohos.bundle.AbilityInfo;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;
import ohos.sensor.agent.CategoryOrientationAgent;
import ohos.sensor.bean.CategoryOrientation;
import ohos.sysappcomponents.settings.SystemSettings;

import com.yc.kernel.utils.VideoLogUtils;
import com.yc.video.bridge.ControlWrapper;
import com.yc.video.config.ConstantKeys;
import com.yc.video.player.InterVideoPlayer;
import com.yc.video.player.VideoPlayer;
import com.yc.video.player.VideoViewManager;
import com.yc.video.tool.NetworkUtils;
import com.yc.video.tool.PlayerUtils;
import com.yc.video.tool.StatesCutoutUtils;
import com.yc.video.ui.view.InterControlView;

import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * 控制器基类
 * 此类集成各种事件的处理逻辑，包括
 * 1.播放器状态改变: {@link #handlePlayerStateChanged(int)}
 * 2.播放状态改变: {@link #handlePlayStateChanged(int)}
 * 3.控制视图的显示和隐藏:
 * 4.播放进度改变: {@link #handleSetProgress(int, int)}
 * 5.锁定状态改变: {@link #handleLockStateChanged(boolean)}
 * 6.设备方向监听: {@link OnOrientationChangeListener#onOrientationChanged(float[] orientation)}
 *
 * @since 2021-05-10
 */
public abstract class BaseVideoController extends StackLayout implements InterVideoController,
    InterViewController, OnOrientationChangeListener, Component.BindStateChangedListener {
    // 方向传感器数据
    private static final int DEFAULT_1 = 1;
    private static final int DEFAULT_2 = 2;
    private static final float ROTATION_0_05 = 0.05f;
    private static final float NEGATIVE_0_43 = 0.43f;
    private static final float NEGATIVE_2_70 = -2.70f;
    private static final float ROTATION_2_71 = 2.71f;
    private static final float ROTATION_2_86 = 2.86f;
    private static final int MATRIX_LENGTH = 9;
    private static final int ROTATION_VECTOR_LENGTH = 9;
    private static final long INTERVAL = 100000000L;
    protected ControlWrapper mControlWrapper; // 播放器包装类，集合了MediaPlayerControl的api和IVideoController的api
    protected Ability mActivity;
    protected boolean mShowing; // 控制器是否处于显示状态
    protected boolean mIsLocked; // 是否处于锁定状态
    protected boolean isPortrait; // 是否处于竖屏播放
    protected int mDefaultTimeout = 5000; // 播放视图隐藏超时
    protected OrientationHelper mOrientationHelper; // 屏幕方向监听辅助类
    private boolean mEnableOrientation; // 是否开启根据屏幕方向进入/退出全屏
    private boolean mAdaptCutout; // 用户设置是否适配刘海屏
    private Boolean mHasCutout; // 是否有刘海
    private int mCutoutHeight; // 刘海的高度
    private boolean mIsStartProgress; // 是否开始刷新进度
    /**
     * 控制是否显示进度条
     */
    public boolean hideToggleState;

    /**
     * 保存了所有的控制组件
     * 使用LinkedHashMap有序
     */
    protected LinkedHashMap<InterControlView, Boolean> mControlComponents = new LinkedHashMap<>();

    // 方向传感器
    private CategoryOrientationAgent sensorManager;
    private int isLeft = -1;
    private Component fullScreenButton;
    private AbilityInfo.DisplayOrientation display;

    /**
     * BaseVideoController
     *
     * @param context
     */
    public BaseVideoController(Context context) {
        // 创建
        this(context, null);
    }

    /**
     * BaseVideoController
     *
     * @param context
     * @param attrs
     */
    public BaseVideoController(Context context, AttrSet attrs) {
        // 创建
        this(context, attrs, "");
    }

    /**
     * BaseVideoController
     *
     * @param context
     * @param attrs
     * @param defStyleAttr
     */
    public BaseVideoController(Context context, AttrSet attrs, String defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView(context);
    }

    @Override
    public void onComponentBoundToWindow(Component component) {
    }

    @Override
    public void onComponentUnboundFromWindow(Component component) {
    }

    /**
     * initView
     *
     * @param context
     */
    protected void initView(Context context) {
        setBindStateChangedListener(this);
        if (getLayoutId() != 0) {
            LayoutScatter.getInstance(context)
                .parse(getLayoutId(), this, true);
        }

        mEnableOrientation = VideoViewManager.getConfig().mEnableOrientation;
        mAdaptCutout = VideoViewManager.getConfig().mAdaptCutout;
        mActivity = PlayerUtils.scanForActivity(context);
        if (mOrientationHelper == null) { // 开始监听设备方向 用到传感器来做
            mOrientationHelper = new OrientationHelper();
            mOrientationHelper.setOnOrientationChangeListener(this);
        }
    }

    /**
     * 设置控制器布局文件，子类必须实现
     *
     * @return return
     */
    protected abstract int getLayoutId();

    /**
     * 重要：此方法用于将{@link VideoPlayer} 和控制器绑定
     *
     * @param mediaPlayer
     */
    public void setMediaPlayer(InterVideoPlayer mediaPlayer) {
        mControlWrapper = new ControlWrapper(mediaPlayer, this);
        for (Map.Entry<InterControlView, Boolean> next : mControlComponents.entrySet()) {
            InterControlView component = next.getKey();
            component.attach(mControlWrapper); // 绑定ControlComponent和Controller
        }
        setSensorManager();
    }

    /**
     * 添加控制组件，最后面添加的在最下面，合理组织添加顺序，可让ControlComponent位于不同的层级
     *
     * @param controlViews view
     */
    @Override
    public void addControlComponent(InterControlView... controlViews) {
        for (InterControlView item : controlViews) {
            addControlComponent(item, false);
        }
    }

    /**
     * 添加控制组件，最后面添加的在最下面，合理组织添加顺序，可让InterControlView位于不同的层级
     *
     * @param controlView view
     * @param isPrivate 是否为独有的组件，如果是就不添加到控制器中
     */
    @Override
    public void addControlComponent(InterControlView controlView, boolean isPrivate) {
        mControlComponents.put(controlView, isPrivate);
        if (mControlWrapper != null) {
            controlView.attach(mControlWrapper);
        }
        Component view = controlView.getView();
        if (view != null && !isPrivate) {
            addComponent(view, 0);
        }
    }

    /**
     * 移除控制组件
     *
     * @param controlView view
     */
    @Override
    public void removeControlComponent(InterControlView controlView) {
        removeComponent(controlView.getView());
        mControlComponents.remove(controlView);
    }

    /**
     * 移除所有的组件
     */
    @Override
    public void removeAllControlComponent() {
        for (Map.Entry<InterControlView, Boolean> next : mControlComponents.entrySet()) {
            removeComponent(next.getKey().getView());
        }
        mControlComponents.clear();
    }

    /**
     * 移除所有独有的组件
     */
    @Override
    public void removeAllPrivateComponents() {
        Iterator<Map.Entry<InterControlView, Boolean>> it = mControlComponents.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry<InterControlView, Boolean> next = it.next();
            if (next.getValue()) {
                it.remove();
            }
        }
    }

    /**
     * 调用此方法向控制器设置播放状态。
     * 这里使用注解限定符，不要使用1，2这种直观数字，不方便知道意思
     * 播放状态，主要是指播放器的各种状态
     * -1 播放错误
     * 0 播放未开始
     * 1 播放准备中
     * 2 播放准备就绪
     * 3 正在播放
     * 4 暂停播放
     * 5 正在缓冲(播放器正在播放时，缓冲区数据不足，进行缓冲，缓冲区数据足够后恢复播放)
     * 6 暂停缓冲(播放器正在播放时，缓冲区数据不足，进行缓冲，此时暂停播放器，继续缓冲，缓冲区数据足够后恢复暂停
     * 7 播放完成
     * 8 开始播放中止
     *
     * @param playState playState
     */
    public void setPlayState(@ConstantKeys.CurrentStateType int playState) {
        // 此方法需要转换到UI主线程，播放完成都是处理UI相关
        // 设置播放器的状态
        post(() -> handlePlayStateChanged(playState));
    }

    /**
     * {@link VideoPlayer}调用此方法向控制器设置播放器模式
     * 播放模式
     * 普通模式，小窗口模式，正常模式三种其中一种
     * MODE_NORMAL              普通模式
     * MODE_FULL_SCREEN         全屏模式
     * MODE_TINY_WINDOW         小屏模式
     *
     * @param playerState
     */
    public void setPlayerState(@ConstantKeys.PlayModeType final int playerState) {
        // 调用此方法向控制器设置播放器状态
        handlePlayerStateChanged(playerState);
    }

    /**
     * 设置播放视图自动隐藏超时
     *
     * @param timeout timeout
     */
    public void setDismissTimeout(int timeout) {
        if (timeout > 0) {
            mDefaultTimeout = timeout;
        } else {
            mDefaultTimeout = 5000;
        }
    }

    /**
     * 隐藏播放视图
     */
    @Override
    public void hide() {
        if (mShowing) {
            stopFadeOut();
            handleVisibilityChanged(false);
            mShowing = false;
        }
    }

    /**
     * 显示播放视图
     */
    @Override
    public void show() {
        if (!mShowing) {
            startFadeOut();
            handleVisibilityChanged(true);
            mShowing = true;
        }
    }

    @Override
    public boolean isShowing() {
        return mShowing;
    }

    /**
     * 开始计时
     */
    @Override
    public void startFadeOut() {
        // 重新开始计时
        stopFadeOut();
        postDelayed(mFadeOut, mDefaultTimeout);
    }

    /**
     * 取消计时
     */
    @Override
    public void stopFadeOut() {
        if (mFadeOut != null) {
            removeCallbacks(mFadeOut);
        }
    }

    /**
     * 隐藏播放视图Runnable
     */
    protected final Runnable mFadeOut = new Runnable() {
        @Override
        public void run() {
            hide();
        }
    };

    /**
     * 设置是否锁屏
     *
     * @param locked 是否锁定
     */
    @Override
    public void setLocked(boolean locked) {
        mIsLocked = locked;
        handleLockStateChanged(locked);
        if (display != null && !isPortrait) {
            int ordinal = display.ordinal();
            if (ordinal == 1) { // 横屏
                mActivity.setDisplayOrientation(AbilityInfo.DisplayOrientation.LANDSCAPE);
            }
        }
    }

    /**
     * 判断是否锁屏
     *
     * @return 返回是否锁屏
     */
    @Override
    public boolean isLocked() {
        return mIsLocked;
    }

    @Override
    public void portraitPlayer(boolean isPortrait) {
        this.isPortrait = isPortrait;
    }

    /**
     * 开始刷新进度，注意：需在STATE_PLAYING时调用才会开始刷新进度
     */
    @Override
    public void startProgress() {
        if (mIsStartProgress) {
            return;
        }
        post(mShowProgress);
        mIsStartProgress = true;
    }

    EventHandler mHandler = new EventHandler(EventRunner.getMainEventRunner());

    private void post(Runnable runnable) {
        mHandler.postTask(runnable);
    }

    private void postDelayed(Runnable runnable, long delayTime) {
        mHandler.postTask(runnable, delayTime);
    }

    private void removeCallbacks(Runnable runnable) {
        mHandler.removeTask(runnable);
    }

    /**
     * 停止刷新进度
     */
    @Override
    public void stopProgress() {
        if (!mIsStartProgress) {
            return;
        }
        removeCallbacks(mShowProgress);
        mIsStartProgress = false;
    }

    /**
     * 刷新进度Runnable
     */
    protected Runnable mShowProgress = new Runnable() {
        @Override
        public void run() {
            setProgress();
            if (mControlWrapper.isPlaying()) {
                postDelayed(this, 1000);
            } else {
                mIsStartProgress = false;
            }
        }
    };

    private int setProgress() {
        int position = (int) mControlWrapper.getCurrentPosition();
        int duration = (int) mControlWrapper.getDuration();
        handleSetProgress(duration, position);
        return position;
    }

    /**
     * 设置是否适配刘海屏
     *
     * @param adaptCutout adaptCutout
     */
    public void setAdaptCutout(boolean adaptCutout) {
        mAdaptCutout = adaptCutout;
    }

    @Override
    public boolean isBoundToWindow() {
        checkCutout();
        return super.isBoundToWindow();
    }

    /**
     * 检查是否需要适配刘海
     */
    private void checkCutout() {
        if (!mAdaptCutout) {
            return;
        }
        if (mActivity != null && mHasCutout == null) {
            mHasCutout = StatesCutoutUtils.allowDisplayToCutout(mActivity);
            if (mHasCutout) {
                // 竖屏下的状态栏高度可认为是刘海的高度
                mCutoutHeight = (int) PlayerUtils.getStatusBarHeightPortrait(mActivity);
            }
        }
        VideoLogUtils.d("hasCutout: " + mHasCutout + " cutout height: " + mCutoutHeight);
    }

    /**
     * 是否有刘海屏
     *
     * @return return
     */
    @Override
    public boolean hasCutout() {
        return mHasCutout != null && mHasCutout;
    }

    /**
     * 刘海的高度
     *
     * @return return
     */
    @Override
    public int getCutoutHeight() {
        return mCutoutHeight;
    }

    /**
     * 显示移动网络播放提示
     *
     * @return 返回显示移动网络播放提示的条件，false:不显示, true显示
     * 此处默认根据手机网络类型来决定是否显示，开发者可以重写相关逻辑
     */
    public boolean showNetWarning() {
        return NetworkUtils.getNetworkType(getContext()) == NetworkUtils.NETWORK_MOBILE
            && !VideoViewManager.instance().playOnMobileNetwork();
    }

    /**
     * 播放和暂停
     */
    protected void togglePlay() {
        mControlWrapper.togglePlay();
    }

    /**
     * 横竖屏切换
     */
    public void toggleFullScreen() {
        if (PlayerUtils.isActivityLiving(mActivity)) {
            mControlWrapper.toggleFullScreen(mActivity);
        }
    }

    /**
     * 子类中请使用此方法来进入全屏
     *
     * @return 是否成功进入全屏
     */
    protected boolean startFullScreen() {
        if (!PlayerUtils.isActivityLiving(mActivity)) {
            return false;
        }
        mActivity.setDisplayOrientation(AbilityInfo.DisplayOrientation.LANDSCAPE);
        mControlWrapper.startFullScreen();
        return true;
    }

    /**
     * 子类中请使用此方法来退出全屏
     *
     * @return 是否成功退出全屏
     */
    protected boolean stopFullScreen() {
        if (!PlayerUtils.isActivityLiving(mActivity)) {
            return false;
        }
        mActivity.setDisplayOrientation(AbilityInfo.DisplayOrientation.PORTRAIT);
        mControlWrapper.stopFullScreen();
        return true;
    }

    /**
     * 改变返回键逻辑，用于activity
     *
     * @return return
     */
    public boolean onBackPressed() {
        return false;
    }

    /**
     * 释放方向传感器
     */
    public void removeSensorManager() {
        if (sensorManager != null) {
            sensorManager.releaseSensorDataCallback(mOrientationHelper,
                sensorManager.getSingleSensor(CategoryOrientation.SENSOR_TYPE_ORIENTATION));
            sensorManager = null;
        }
    }

    /**
     * 注册方向传感器
     */
    public void setSensorManager() {
        if (sensorManager == null) {
            synchronized (BaseVideoController.class) {
                sensorManager = new CategoryOrientationAgent();
                sensorManager.setSensorDataCallback(mOrientationHelper,
                    sensorManager.getSingleSensor(CategoryOrientation.SENSOR_TYPE_ORIENTATION), INTERVAL); // 方向传感器
            }
        }
    }

    /**
     * 是否自动旋转， 默认不自动旋转
     *
     * @param enableOrientation enableOrientation
     */
    public void setEnableOrientation(boolean enableOrientation) {
        mEnableOrientation = enableOrientation;
    }

    /**
     * orientationChanged
     *
     * @param display display
     */
    public void orientationChanged(AbilityInfo.DisplayOrientation display) {
        if (mActivity == null || !PlayerUtils.isActivityLiving(mActivity)) {
            return;
        }
        this.display = display;
        if (display.equals(AbilityInfo.DisplayOrientation.PORTRAIT)) { // 竖屏

            fullScreenButton.setSelected(false);
            if (hideToggleState) {
                setHideToggleState();
            }

            ControlWrapper.defaultValue();
            onOrientationPortrait(mActivity);
        } else if (display.equals(AbilityInfo.DisplayOrientation.LANDSCAPE)) { // 横屏

            fullScreenButton.setSelected(true);
            if (hideToggleState) {
                setShowToggleState();
            }

            ControlWrapper.setLandscapeFlag(true);
            ControlWrapper.setPortraitFlag(false);
            if (isLeft == 0) {
                onOrientationLandscape(mActivity);
            }
        }
    }

    /**
     * 设置显示底部控制器
     */
    public void setShowToggleState() {
        new EventHandler(EventRunner.getMainEventRunner()).postTask(new Runnable() {
            @Override
            public void run() {
                mControlWrapper.setToggleState(1);
                mControlWrapper.hideTextSetLayout(mContext);
                mControlWrapper.show();
            }
        });
    }

    /**
     * 设置隐藏底部控制器
     */
    public void setHideToggleState() {
        new EventHandler(EventRunner.getMainEventRunner()).postTask(new Runnable() {
            @Override
            public void run() {
                mControlWrapper.setToggleState(0);
                mControlWrapper.showTextResetLayout();
                mControlWrapper.hide();
            }
        });
    }

    /**
     * 竖屏
     *
     * @param activity activity
     */
    protected void onOrientationPortrait(AbilityContext activity) {
        if (mIsLocked) { // 屏幕锁定的情况
            return;
        }
        if (!mEnableOrientation) { // 没有开启设备方向监听的情况
            return;
        }
        activity.setDisplayOrientation(AbilityInfo.DisplayOrientation.PORTRAIT);
        mControlWrapper.stopFullScreen();
    }

    /**
     * 横屏
     *
     * @param activity activity
     */
    protected void onOrientationLandscape(AbilityContext activity) {
        new EventHandler(EventRunner.getMainEventRunner()).postTask(new Runnable() {
            @Override
            public void run() {
                activity.setDisplayOrientation(AbilityInfo.DisplayOrientation.LANDSCAPE);
                if (mControlWrapper.isFullScreen()) {
                    handlePlayerStateChanged(ConstantKeys.PlayMode.MODE_FULL_SCREEN);
                } else {
                    mControlWrapper.startFullScreen();
                }
            }
        });
    }

    /**
     * 反向横屏
     *
     * @param activity activity
     */
    protected void onOrientationReverseLandscape(AbilityContext activity) {
        new EventHandler(EventRunner.getMainEventRunner()).postTask(new Runnable() {
            @Override
            public void run() {
                activity.setDisplayOrientation(AbilityInfo.DisplayOrientation.LANDSCAPE);
                if (mControlWrapper.isFullScreen()) {
                    handlePlayerStateChanged(ConstantKeys.PlayMode.MODE_FULL_SCREEN);
                } else {
                    mControlWrapper.startFullScreen();
                }
            }
        });
    }

    private void handleVisibilityChanged(boolean isVisible) {
        if (!mIsLocked) {
            // 没锁住时才向ControlComponent下发此事件
            for (Map.Entry<InterControlView, Boolean> next : mControlComponents.entrySet()) {
                InterControlView component = next.getKey();
                component.onVisibilityChanged(isVisible, createAnimator(isVisible)); // 创建不同的动画，防止同一个动画被设置了Target，导致动画还没执行完就被设置了Target，这样就没用了
            }
        }
        onVisibilityChanged(isVisible, createAnimator(isVisible));
    }

    private Animator createAnimator(boolean isShow) {
        if (isShow) {
            return createAnimatorProperty().alphaFrom(0).alpha(1).setDuration(300);
        } else {
            return createAnimatorProperty().alphaFrom(1).alpha(1).setDuration(2000);
        }
    }

    /**
     * 子类重写此方法监听控制的显示和隐藏
     *
     * @param isVisible 是否可见
     * @param anim 显示/隐藏动画
     */
    protected void onVisibilityChanged(boolean isVisible, Animator anim) {
    }

    private void handlePlayStateChanged(int playState) {
        for (Map.Entry<InterControlView, Boolean> next : mControlComponents.entrySet()) {
            InterControlView component = next.getKey();
            component.onPlayStateChanged(playState);
        }
        onPlayStateChanged(playState);
    }

    /**
     * 子类重写此方法并在其中更新控制器在不同播放状态下的ui
     *
     * @param playState
     */
    protected void onPlayStateChanged(int playState) {
        switch (playState) {
            case ConstantKeys.CurrentState.STATE_IDLE:
                mIsLocked = false;
                mShowing = false;
                break;
            case ConstantKeys.CurrentState.STATE_BUFFERING_PLAYING:
                mIsLocked = false;
                mShowing = false;
                break;
            case ConstantKeys.CurrentState.STATE_ERROR:
                mShowing = false;
                break;
            default:
                break;
        }
    }

    /**
     * 播放器状态改变
     *
     * @param playerState 播放器状态
     */
    private void handlePlayerStateChanged(int playerState) {
        for (Map.Entry<InterControlView, Boolean> next : mControlComponents.entrySet()) {
            InterControlView component = next.getKey();
            component.onPlayerStateChanged(playerState);
        }
        onPlayerStateChanged(playerState);
    }

    /**
     * 子类重写此方法并在其中更新控制器在不同播放器状态下的ui
     * 普通模式，小窗口模式，正常模式三种其中一种
     * MODE_NORMAL              普通模式
     * MODE_FULL_SCREEN         全屏模式
     * MODE_TINY_WINDOW         小屏模式
     *
     * @param playerState playerState
     */
    protected void onPlayerStateChanged(@ConstantKeys.PlayMode int playerState) {
        switch (playerState) {
            case ConstantKeys.PlayMode.MODE_NORMAL:
                // 视频正常播放是设置监听
                break;
            case ConstantKeys.PlayMode.MODE_FULL_SCREEN:
                // 在全屏时强制监听设备方向
                break;
            case ConstantKeys.PlayMode.MODE_TINY_WINDOW:
                // 小窗口取消重力感应监听
                break;
            default:
                break;
        }
    }

    private void handleSetProgress(int duration, int position) {
        for (Map.Entry<InterControlView, Boolean> next : mControlComponents.entrySet()) {
            InterControlView component = next.getKey();
            component.setProgress(duration, position);
        }
        setProgress(duration, position);
    }

    /**
     * 刷新进度回调，子类可在此方法监听进度刷新，然后更新ui
     *
     * @param duration 视频总时长
     * @param position 视频当前时长
     */
    protected void setProgress(int duration, int position) {
    }

    private void handleLockStateChanged(boolean isLocked) {
        for (Map.Entry<InterControlView, Boolean> next : mControlComponents.entrySet()) {
            InterControlView component = next.getKey();
            component.onLockStateChanged(isLocked);
        }
        onLockStateChanged(isLocked);
    }

    /**
     * 子类可重写此方法监听锁定状态发生改变，然后更新ui
     *
     * @param isLocked isLocked
     */
    protected void onLockStateChanged(boolean isLocked) {
    }

    public ControlWrapper getControlWrapper() {
        return mControlWrapper;
    }

    public void setHideToggleShowState(boolean state) {
        hideToggleState = state;
    }

    public void setFullScreenButton(Component bt) {
        fullScreenButton = bt;
    }

    public Component getFullScreenButton() {
        return fullScreenButton;
    }

    @Override
    public void onOrientationChanged(float[] orientation) {
        DataAbilityHelper dataAbilityHelper = DataAbilityHelper.creator(mActivity);
        String value = SystemSettings.getValue(dataAbilityHelper, SystemSettings.General.ACCELEROMETER_ROTATION_STATUS);
        if ("0".equals(value)) {
            if (mActivity.getDisplayOrientation() == -1) {
                orientationChanged(AbilityInfo.DisplayOrientation.PORTRAIT);
            }
            return;
        }
        if (orientation[1] > 40 || orientation[1] < -40) { // 竖屏
            if (ControlWrapper.isLandscapeFlag()) {
                return;
            }
            if (ControlWrapper.isPortraitFlag()) {
                if (!mIsLocked) {
                    mActivity.setDisplayOrientation(AbilityInfo.DisplayOrientation.UNSPECIFIED);
                }
            }
        }

        // 横屏
        if (orientation[2] > 40 || orientation[2] < -40) {
            if (orientation[2] > 40) { // 左边
                isLeft = 0;
            } else if (orientation[2] < -40) { // 右边
                isLeft = 1;
            }
            if (ControlWrapper.isPortraitFlag()) {
                return;
            }
            if (!mIsLocked) {
                mActivity.setDisplayOrientation(AbilityInfo.DisplayOrientation.UNSPECIFIED);
            }
        }
    }
}
